/**
 * jGrid plugin depend on jQuery.js and DWZ.js
 * 
 * @param {type} $ jQuery
 * @param {type} win window
 * @returns {undefined}
 */
var DWZ = DWZ || {}, alertMsg = alertMsg || {}, navTab = navTab || {};
(function($, win, DWZ, alertMsg, navTab) {
	var queryButtonText = queryButtonText || '查询', advancedQueryText = advancedQueryText || '高级查询', pagePanelShow = pagePanelShow || '显示', pagePanelTotal = pagePanelTotal || '共', pagePanelTotalItems = pagePanelTotalItems || '条', queryColon = queryColon || '：', noRightDescription = noRightDescription || '没有权限操作', checkParameters = function(args) {
		if (args.length === 0 || (!$.isPlainObject(args[0]) && typeof args[0] !== "string")) {
			console.error("Invalid parameter.");
			return false;
		}
		return true;
	}, 
	// 列属性转换为条件查询属性
	columnToQuery = function(column) {
		var query = {};
		$.each(column, function(key, value) {
			if (key === 'queryField') {
				query.field = value;
			} else if (key === 'queryType') {
				query.type = value;
			} else if (key === 'queryOptions') {
				query.options = value;
			} else if (key === 'queryRender') {
				query.render = value;
			} else {
				if (key === 'field' && column.queryField) {
					return true;
				}
				query[key] = value;
			}
		});
		return query;
	}, 
	// 工具
	_$ = {
		// 节流器，间隔时间内连续相同的操作仅执行最后一次
		throttle: function() {
			var isClear = arguments[0], fn;
			if (typeof isClear === 'boolean') {
				fn = arguments[1];
				fn.__throttleId && clearTimeout(fn.__throttleId);
			} else {
				fn = isClear;
				var param = arguments[1], p = $.extend({
					context: null,
					args: [],
					time: 300
				}, param);
				arguments.callee(true, fn);
				fn.__throttleId = setTimeout(function() {
					fn.apply(p.context, p.args);
				}, p.time);
			}
		},
		// 缓行器，连续相同的操作每间隔一段时间执行一次
		amble: function() {
			var fn = arguments[0], param = arguments[1], p = $.extend({
				context: null,
				args: [],
				time: 300
			}, param), time = new Date().getTime(), throttleId = fn.__throttleId;
			if (!fn.__prevtime) {
				fn.apply(p.context, p.args);
				fn.__prevtime = time;
			} else {
				if (time > fn.__prevtime + p.time) {
					fn.apply(p.context, p.args);
					fn.__prevtime = time;
				}
				// 最后一次执行
				//_$.throttle(fn, param);
			}
		},
		// 获取事件触发位置
		getEventPosition: function(dom, e) {
			var rect = dom && dom.getBoundingClientRect(), event = e || window.event;
			return event && dom && {
				left: event.clientX - rect.left,
				top: event.clientY - rect.top,
				width: rect.width,
				height: rect.height
			};
		}
	};

	$.fn.extend({
		// 获取输入框的标准日期（非字符串）
		getDate: function() {
			var value = $(this).val().trim(), format = arguments[0] || 'yyyy-MM-dd';
			if (!value) {
				return '';
			}
			try {
				return value.parseDate(format);
			} catch (e) {
				console.error(e);
			}
			return value;
		},
		// 树表组件，基于jGrid组件，配置默认属性
		jTreeGrid: function() {
			if (!checkParameters(arguments)) {
				return;
			}
			if ($.isPlainObject(arguments[0])) {
				var ops = $.extend(true, arguments[0], {
					orderable: false,
					pageable: false,
					treeTable: true,
					treeModel: 'collapsed' // 'expanded' || 'collapsed'
				});
				return this.jGrid(ops);
			} else {
				return this.jGrid(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4]);
			}
		},
		// jGrid组件
		jGrid: function() {
			if (!checkParameters(arguments)) {
				return;
			}
			if ($.isPlainObject(arguments[0])) {
				// 列表生成
				var ops = arguments[0];
				return this.each(function() {
					var grid = {}, $this = $(this), $form;
					// 默认属性
					grid.options = {
						// 表宽
						width: 0,
						// layoutH布局
						layoutH: 0,
						// 表头高度
						gridHeaderHeight: 27,
						// url根路径
						base: '',
						// ajax数据源
						url: '',
						// 初始查询条件
						data: {},
						// 立即自动加载数据
						autoLoad: true,
						// td内包裹div
						wrapTD: true,
						// 表格边框
						hasBorder: false,
						// 行可选中
						trselectable: true,
						// 表格列
						columns: [],
						// 表格列宽度可变
						columnresizeable: true,
						// Shift + 鼠标左键 可选中多行的checkbox
						_shiftbox: '',
						// 列固定
						lockColumnNum: 0,
						// 排序
						orderable: true,
						// 单列排序或多列排序 'multiple' || 'single'
						ordertype: 'single',
						// 分页查询
						pageable: true,
						page: {
							pageNum: 1,
							numPerPage: 20,
							pageNumShown: 5,
							numPerPages: [10, 20, 30, 50, 100, 200]
						},
						pagination: {},
						// 条件查询
						queryable: false,
						query: {
							button: queryButtonText,
							numPerRow: 3,
							queryfields: [],
							advancedqueryfields: []
						},
						// 列表按钮
						gridbars: [],
						// 填充的数据， autoLoad为false时会生效，否则会调用ajax获取的数据
						fillData: [],
						// 数据填充完的回调
						fillcallback: $.noop,
						// 内部表
						inner: false,
						// 行可拖拽排序
						rowsortable: false
					};
					$.extend(true, grid.options, ops);
					// 内部表时默认设置相应属性
					if (grid.options.inner) {
						grid.options.columnresizeable = false;
						grid.options.orderable = false;
						grid.options.pageable = false;
						grid.options.queryable = false;
					}
					// 没有使用layoutH布局且设置高度为100%时
					if (grid.options.layoutH === 0 && (grid.options.height === 0 || grid.options.height === '100%')) {
						grid.options.height = $this.height() - 30;
					}
					// 生成随机字符串
					var getRandomStr = function() {
						return Math.random().toString(36).substring(2);
					}, 
					// 转换条件，选中单行时的操作，例如编辑、详情
					transformData = function(bar, postData) {
						var data = bar.data || {}, needSelectedTr = false, needSelectedCheckbox = false;
						$.extend(postData, {
							_grid: grid._gridId
						});
						$.each(data, function(key, value) {
							if (/^\{.*\}$/.test(value)) {
								if (grid.options.checkGroup === value.slice(1, -1)) {
									bar.select = bar.select || key;
									needSelectedCheckbox = true;
								} else {
									needSelectedTr = true;
								}
								return false;
							}
						});
						if (bar.select && bar.select === grid.options.checkGroup) {
							needSelectedCheckbox = true;
						}
						if (needSelectedTr) {
							if (grid.tbody.find('tr.selected').length === 0) {
								alertMsg.error(bar.warn || DWZ.msg("alertSelectMsg"));
								return false;
							}
							var trData = grid.tbody.find('tr.selected:first').data();
							$.each(data, function(key, value) {
								if (/^\{.*\}$/.test(value)) {
									if (trData[value.slice(1, -1)] !== null) {
										postData[key] = trData[value.slice(1, -1)];
									} else {
										postData[key] = '';
									}
								} else if (/^\$\(.*\)$/.test(value)) {
									try {
										postData[key] = eval(value.slice(2, -1));
									} catch (e) {
										console.error("Global variable is not existing. " + e);
									}
								} else if ($.isFunction(value)) {
									postData[key] = value(trData);
								} else {
									postData[key] = value;
								}
							});
						} else if (needSelectedCheckbox) {
							return transformSelectData(bar, postData);
						} else {
							$.extend(true, postData, data);
						}
						return true;
					}, 
					// 选中多行的checkbox的选中值
					transformSelectData = function(bar, data) {
						$.extend(true, data, bar.data || {});
						var ids = '';
						$.each(grid.tbody.find('input[type="checkbox"][name="' + grid.options.checkGroup + '"]'), function() {
							if (this.checked) {
								ids += (this.value + ',');
							}
						});
						if (!ids) {
							alertMsg.error(DWZ.msg("alertSelectMsg"));
							return false;
						} else {
							ids = ids.slice(0, -1);
						}
						data[bar.select] = ids;
						$.each(data, function(key, value) {
							if (/^\$\(.*\)$/.test(value)) {
								try {
									data[key] = eval(value.slice(2, -1));
								} catch (e) {
									console.error("Global variable is not existing. " + e);
								}
							}
						});
						return true;
					}, 
					// 生成列表按钮
					createGridBar = function() {
						var $gridBar = $('<div/>').addClass('panelBar headBar'), $bars = $('<ul/>').addClass('toolBar'), 
						// 按钮默认支持dialog（一般用于新增、编辑、详情等）、selectedTodo（一般用于删除操作）、navTab（标签页）、ajaxTodo（ajax请求）、confirmTodo（确认？）、action（自定义处理）、export（列表导出功能）
						// 各个功能现在系统中均有实现，后端请参照相应的代码自行实现，前端只是进行了高度封装，尽量减少前后端的编码
						targets = ['dialog', 'selectedTodo', 'navTab', 'ajaxTodo', 'confirmTodo', 'action', 'export'];
						$.each(grid.options.gridbars, function(barIndex, bar) {
							var $bar;
							//HAS_ALL_ACCESSDECISION新增超级管理员
							if (bar.menuCode && window.buttonAuthorities && !window.buttonAuthorities[bar.menuCode.toUpperCase()]
							&& !window.buttonAuthorities['HAS_ALL_ACCESSDECISION']) {				
								var noRight = "<li><a class='noright' title='" + noRightDescription + "'><span style='color:#D8D1D1;'>" + bar.text + "</span></a></li>";
								$bar = $(noRight).appendTo($bars);
								$bar.on('click', 'a.noright', function(event) {
									var title = $(this).attr("title");
									alertMsg.error(title);
									event.preventDefault();
								});
								return true;
							}
							if (bar.type === 'button') {
								$bar = $('<div class="buttonActive"/>').append($('<div class="buttonContent"/>').append($('<button/>').text(bar.text)));
							} else {
								$bar = $('<a/>').addClass(bar.icon || '').attr({
									title: bar.title,
									rel: bar.rel,
									href: (targets.indexOf && targets.indexOf(bar.target) !== -1 || checkIndexOf(targets, bar.target) !== -1) ? 'javascript:void(0);' : grid.options.base + bar.href,
									target: (targets.indexOf && targets.indexOf(bar.target) !== -1 || checkIndexOf(targets, bar.target) !== -1) ? '' : bar.target,
									targetType: bar.targetType
								}).append($('<span/>').append(bar.text));
							}
							$bar.on('click', function(event) {
								$('#calendar', $('body')).remove();
								if (bar.preCheck && $.isFunction(bar.preCheck) && !bar.preCheck.apply(bar, [$bar])) {
									return false;
								}
								if (!bar.href && !bar.action) {
									return false;
								}
								if (bar.target === 'dialog') {
									var url = grid.options.base + bar.href, rel = bar.rel || getRandomStr(), title = bar.title || bar.text, data = {}, options = {};
									DWZ.debug(url);
									if (!url.isFinishedTm()) {
										return false;
									}
									if (!transformData(bar, data)) {
										return false;
									}
									options.data = data;
									options.max = bar.max || false;
									options.mask = bar.mask || true;
									options.maxable = bar.maxable || false;
									options.minable = bar.minable || false;
									options.fresh = bar.fresh || true;
									options.resizable = bar.resizable || false;
									options.drawable = bar.drawable || true;
									options.close = bar.close || '';
									options.param = bar.param || '';
									options._lookup = bar._lookup;
									var $parent = $this.closest('.dialogContent.unitBox');
									if ($parent.length === 0) {
										$parent = $this.closest('.page.unitBox');
									}
									options._parent = $parent;
									if (bar.width)
										options.width = bar.width;
									if (bar.height)
										options.height = bar.height;
									if (bar.preevent) {
										if ($.isFunction(bar.preevent) && !bar.preevent()) {
											return false;
										} else if (typeof bar.preevent === 'string' && !eval(bar.preevent + "()")) {
											return false;
										}
									}
									$.pdialog.open(url, rel, title, options);
									event.preventDefault();
								} else if (bar.target === 'selectedTodo') {
									var url = grid.options.base + bar.href, data = {};
									DWZ.debug(url);
									if (!url.isFinishedTm()) {
										return false;
									}
									if (!transformData(bar, data)) {
										return false;
									}
									var _doPost = function() {
										DWZ.ajax({
											type: 'POST',
											url: url,
											dataType: 'json',
											cache: false,
											data: data,
											alert: false,
											success: function(json) {
												$.jGridTool.loadData(grid);
												if (json.data) {
													if (!DWZ.showDetailedReports(json) && json[DWZ.keys.message] && alertMsg) {
														alertMsg.correct(json[DWZ.keys.message]);
													}
												} else if (json[DWZ.keys.message] && alertMsg) {
													alertMsg.correct(json[DWZ.keys.message]);
												}
											}
										});
									};
									if (bar.title) {
										if ($.isFunction(bar.action)) {
											alertMsg.confirm(bar.title, {
												okCall: function() {
													bar.action(data);
												}
											});
										} else {
											alertMsg.confirm(bar.title, {
												okCall: _doPost
											});
										}
									} else {
										if ($.isFunction(bar.action)) {
											bar.action(data);
										} else {
											_doPost();
										}
									}
									event.preventDefault();
								} else if (bar.target === 'navTab') {
									var title = bar.title || bar.text, tabid = bar.rel || getRandomStr(), fresh = bar.fresh || true, external = bar.external || false, url = grid.options.base + bar.href, data = {};
									DWZ.debug(url);
									if (!url.isFinishedTm()) {
										return false;
									}
									if (!transformData(bar, data)) {
										return false;
									}
									navTab.openTab(tabid, url, {
										data: data,
										title: title,
										fresh: fresh,
										external: external
									});
									event.preventDefault();
								} else if (bar.target === 'ajaxTodo') {
									var title = bar.title, url = grid.options.base + bar.href, data = {};
									DWZ.debug(url);
									if (!url.isFinishedTm()) {
										return false;
									}
									if (!transformData(bar, data)) {
										return false;
									}
									if (title) {
										alertMsg.confirm(title, {
											okCall: function() {
												ajaxTodo(url, bar.callback, data);
											}
										});
									} else {
										ajaxTodo(url, bar.callback, data);
									}
									event.preventDefault();
								} else if (bar.target === 'confirmTodo') {
									if (bar.title) {
										alertMsg.confirm(bar.title, {
											okCall: bar.action
										});
									} else {
										bar.action.apply(bar);
									}
									event.preventDefault();
								} else if (bar.target === 'action' && $.isFunction(bar.action)) {
									bar.action.apply(bar);
									event.preventDefault();
								} else if (bar.target === 'export') {
									// 列表导出，有详细的注释
									if ($('>tr .noData', grid.tbody).length || $('>tr', grid.tbody).length === 0) {
										alertMsg.error('没有可导出的数据！');
										return false;
									}
									var _doExport = function() {
										var url = grid.options.base + bar.href, $exportForm = $('body').data('_exportForm'), cols = {
											_length: 0
										},
										// 往form里添加input标签，从而支持大数据量的参数
										appendFieldInput = function(name, value) {
											$exportForm.append($('<input type="text" name="' + name + '">').val(value));
										};
										// 创建专门下载使用的form
										if (!$exportForm) {
											$exportForm = $('<form id="_exportForm" method="POST"/>').hide().appendTo($('body'));
											$('body').data('_exportForm', $exportForm);
										}
										// 清空form，避免上次下载时遗留的无用的参数
										$exportForm.empty();
										// 组装导出列的表头数据，后台只需要接收colsMap字符串，反序列化为LinkedHashMap即可，
										// 不用定义map再往里面put各个表头的字段及描述
										$.each(grid.options.columns, function() {
											if (this.field === '_index' || this.field === '_lookup') {
												return true;
											}
											// 可以单独定义后台导出的字段exportField，默认就是表头字段field
											var exportField = this.exportField || this.field;
											cols[exportField] = this.text;
											cols._length = cols._length + 1;
										});
										// 如果有导出的列
										if (cols._length > 0) {
											delete cols._length;
											var colsMap = JSON.stringify(cols);
											appendFieldInput('colsMap', colsMap);
										}
										// 支持对有分页的列表导出全部，后台使用带分页的接口查询即可，不用再重新定义单独的接口
										// 原理是设置页码为1，
										// 每页的数量为查出来的数据总量totalCount，请酌情使用，excel最大支持的行数为65535
										var _export = {};
										if (grid.options.pageable && bar.exportAll) {
											_export = {
												pageNum: 1,
												startRow: 1,
												numPerPage: grid.options.pagination.totalCount,
												endRow: grid.options.pagination.totalCount
											};
										}
										// 获取查询列表时的参数，并且加入传入的额外的参数及是否导出全部的参数
										var postData = $.extend(true, {}, grid.options.postData, _export, bar.data || {});
										// 将参数转换为url的参数格式
										var param = $.param(postData);
										// 将url设置给form的action属性
										$exportForm.attr({
											action: url + (url.indexOf('?') === -1 ? "?" : "&") + param
										});
										// 提交form表单，实现下载
										$exportForm.submit();
										// 删除form表单的action属性
										$exportForm.removeAttr('action');
									};
									if (bar.title) {
										alertMsg.confirm(bar.title, {
											okCall: _doExport
										});
									} else {
										_doExport();
									}
									event.preventDefault();
								}
							});
							var $li = $('<li class=""/>').append($bar).appendTo($bars);
							if (bar.id || bar.menuCode) {
								$li.attr('id', (bar.id || bar.menuCode));
							}
							if ($.isFunction(bar.render)) {
								bar.render($li);
							}
						});
						return $gridBar.append($bars);
					}, 
					// 生成表格主体
					appendGrid = function() {
						var $grid = $('<div/>').addClass('grid gridPart'), $gridScrollerBar = $('<div/>').addClass('gridScrollerBar').css({
							overflowX: 'auto'
						}).append('<div/>'), $gridHeader = $('<div/>').addClass('gridHeader'), gridWith = grid.options.hasBorder ? $this.width() - 1 : $this.width(), $gridBody = $('<div/>').addClass('gridBody'), $resizeMarker = $('<div/>').addClass('resizeMarker').css({
							height: '300px',
							left: '57px',
							display: 'none'
						}), $resizeProxy = $('<div>').addClass('resizeProxy').css({
							height: '300px',
							left: '377px',
							display: 'none'
						}), $thead = $('<thead/>').appendTo($('<table/>').appendTo($('<div/>').addClass('gridThead').appendTo($gridHeader))), $tbody = $('<tbody/>').appendTo($('<table/>').addClass(grid.options.treeTable ? 'treetable' : '').appendTo($('<div/>').addClass('gridTbody').appendTo($gridBody))), getTrIndex = function($tr) {
							var index = 0, $tr = $tr.prev('tr');
							while ($tr.length) {
								index++;
								$tr = $tr.prev('tr');
							}
							return index;
						};

						// 事件委托机制，绑定事件到tbody上，不依赖于已存在的$trs
						$tbody.on('click', 'tr', function(event) {
							var e = event || window.event, $tr = $(this), oldIndex = -1, newIndex = -1;
							if (grid.options._shiftbox && e.shiftKey) {
								if ($('>tr.selected', $tbody).length) {
									oldIndex = getTrIndex($('>tr.selected:first', $tbody));
								}
								newIndex = getTrIndex($tr);
								if (oldIndex !== -1 && newIndex !== -1 && oldIndex !== newIndex) {
									$('>tr :checkbox[name="' + grid.options._shiftbox + '"]', $tbody).attr({
										checked: false
									});
									var start = oldIndex > newIndex ? newIndex : oldIndex, end = oldIndex < newIndex ? newIndex : oldIndex;
									for (var int = start; int <= end; int++) {
										$('>tr:eq(' + int + ') :checkbox[name="' + grid.options._shiftbox + '"]', $tbody)[0].checked = true;
									}
								}
							}
							if (grid.options.trselectable) {
								$('>tr.selected', $tbody).removeClass('selected');
								$tr.addClass('selected');
							}
							if ($.isFunction(grid.options.trclick)) {
								grid.options.trclick($tr, $tr.data(), grid.options.troptions || {});
							}
						});
						if ($.isFunction(grid.options.trdblclick)) {
							$tbody.on('dblclick', 'tr', function(event) {
								var $tr = $(this);
								grid.options.trdblclick($tr, $tr.data(), grid.options.troptions || {});
							});
						}

						$tbody.on('mouseenter', 'tr', function() {
							$(this).addClass('hover');
						}).on('mouseleave', 'tr', function() {
							$(this).removeClass('hover');
						});

						grid.options.rowsortable && !function() {
							var mosudown = false, _rows = null, target, detached = false, appendRow = function(row) {
								if (!isNaN(_rows)) {
									if (_rows === 0) {
										$tbody.prepend(row);
									} else if (_rows === $tbody.find('>tr:not(.sortDragOccupancy)').length) {
										$tbody.append(row);
									} else {
										$tbody.find('>tr:not(.sortDragOccupancy):eq(' + (_rows - 1) + ')').after(row);
									}
								}
								$.jGridTool.refresh(grid);
							},
							// 拖拽
							drag = function($ele, e) {
								var $rows = $tbody.find('>tr:not(.sortDragOccupancy)'), $first = $rows.eq(0), rowH = $first.height(), rows = Math.floor((_$.getEventPosition($ele[0], e).top + $ele.scrollTop()) / rowH);
								rows = Math.min(rows, $rows.length);
								if (rows !== _rows) {
									var $temp = $first.clone();
									$temp.addClass('sortDragOccupancy').css({
										height: '5px',
										background: '#CEF8CE'
									});
									$temp.find('>td').each(function() {
										$(this).empty();
									});
									$tbody.find('.sortDragOccupancy').remove();
									_rows = rows;
									appendRow($temp);
								}
							}, drop = function() {
								if (target && !isNaN(_rows)) {
									if (mosudown) {
										$tbody.find('.sortDragOccupancy').remove();
									}
									appendRow(target);
									detached = false;
									mosudown = false;
									_rows = null;
									target = null;
									$tbody.css('cursor', '');
								}
							};

							$tbody.on('mousedown', 'tr', function(e) {
								var tagName = e.target && e.target.tagName && e.target.tagName.toLowerCase();
								if ($tbody.find('>tr:not(.sortDragOccupancy)').length <= 1 || tagName == 'input' || tagName == 'select' || tagName == 'button') {
									return;
								}
								mosudown = true;
								$tbody.css('cursor', 'move');
								target = $(this);
							});
							$gridBody.on('mouseleave', drop).on('mousemove', function(e) {
								if (mosudown && target) {
									if (target && !detached) {
										target.detach();
										$.jGridTool.refresh(grid);
									}
									//drag(e);
									_$.amble(drag, {
										args: [$gridBody, e]
									});
								}
							});
							$(document).on('mouseup', drop);
						}();

						grid.thead = $thead;
						grid.tbody = $tbody;
						grid.orders = {};
						grid.defaultOrderString = grid.options.defaultOrderString || '';
						grid._gridId = getRandomStr();
						$this.attr('grid-id', grid._gridId);
						$gridScrollerBar.scroll(function(event) {
							var scroll = $gridScrollerBar.scrollLeft();
							$(".gridThead, .gridTbody", $grid).css({
								position: 'relative',
								left: 0 - scroll
							});
							if (grid.options.lockColumnNum > 0) {
								$.jGridTool.lockColumn(grid);
							}
							return false;
						});
						$grid.append($gridHeader).append($gridBody).append($gridScrollerBar).append($resizeMarker).append($resizeProxy).appendTo($this);
						$.jGridTool.fillGridHeader(grid);
					}, 
					// 生成分页
					createPageBar = function() {
						var $pagePanel = $('<div class="panelBar footBar"/>'), $pages = $('<div class="pages"/>'), $pagination = $('<span class="pagination"/>'), $select = $('<select class="combox" />').attr('name', 'numPerPage');

						$.each(grid.options.page.numPerPages, function() {
							var $op = $('<option/>').text(this).attr({
								value: this
							}).appendTo($select);
							if (this == grid.options.page.numPerPage) {
								$op.attr({
									selected: 'selected'
								});
							}
						});

						$pages.append('<span>' + pagePanelShow + '</span>').append($select).append('<span>' + pagePanelTotal + '</span>').append('<span name="totalCount">0' + pagePanelTotalItems + '</span>');

						grid.pagination = $pagination;
						createPagination();
						$select.combox();
						$('#op_' + $select.parent().attr('id') + '>li>a').on('click', function() {
							setPerPage(parseInt($(this).attr('value')));
						});
						$pagePanel.append($pages).append($pagination);
						grid.pagePanel = $pagePanel;
						grid.page = {
							numPerPage: grid.options.page.numPerPage,
							pageNum: grid.options.page.pageNum,
							startRow: (grid.options.page.pageNum - 1) * grid.options.page.numPerPage + 1,
							endRow: grid.options.page.pageNum * grid.options.page.numPerPage
						};
						return $pagePanel;
					}, 
					// 分页导航
					createPagination = function() {
						var $pagination = grid.pagination;

						grid.firstPage = $('<li class="j-first disabled"/>').append($('<a class="first"/>').append($('<span>').append('首页')).hide().on('click', function() {
							setPageNum(1);
						})).append($('<span class="first"/>').append($('<span>').append('首页')));
						grid.prevPage = $('<li class="j-prev disabled"/>').append($('<a class="previous"/>').append($('<span>').append('上一页')).hide().on('click', function() {
							setPageNum(grid.page.pageNum - 1);
						})).append($('<span class="previous"/>').append($('<span>').append('上一页')));
						grid.nextPage = $('<li class="j-next disabled"/>').append($('<a class="next"/>').append($('<span>').append('下一页')).hide().on('click', function() {
							setPageNum(grid.page.pageNum + 1);
						})).append($('<span class="next"/>').append($('<span>').append('下一页')));
						grid.lastPage = $('<li class="j-last disabled"/>').append($('<a class="last"/>').append($('<span>').append('末页')).hide().on('click', function() {
							setPageNum(parseInt(grid.pagination.data('totalPageNum')));
						})).append($('<span class="last"/>').append($('<span>').append('末页')));
						grid.jumpto = $('<li class="jumpto disabled"/>').append($('<input type="text" style="line-height: 15px;" class="textInput integer"/>').on('keyup', function(event) {
							var e = event || window.event;
							if (e.keyCode === 13) {
								$(this).next('input').click();
							}
						})).append($('<input type="button" class="goto"/>').on('click', function() {
							var toNum = 1;
							try {
								toNum = parseInt($(this).prev('input').val());
								if (toNum < 0 || toNum === 0)
									return false;
							} catch (e) {
								return false;
							}
							if (toNum < parseInt(grid.pagination.data('totalPageNum')) || toNum === parseInt(grid.pagination.data('totalPageNum'))) {
								setPageNum(toNum);
							}
						}));
						$('<ul/>').append(grid.firstPage).append(grid.prevPage).append(grid.nextPage).append(grid.lastPage).append(grid.jumpto).appendTo($pagination);
					}, 
					// 分页跳转
					setPageNum = function(num) {
						grid.page.pageNum = num;
						grid.page.startRow = (num - 1) * grid.page.numPerPage + 1;
						grid.page.endRow = num * grid.page.numPerPage;
						$.jGridTool.loadData(grid);
					}, setPerPage = function(numPerPage) {
						grid.page.numPerPage = numPerPage;
						grid.page.pageNum = 1;
						grid.page.startRow = 1;
						grid.page.endRow = numPerPage;
						$.jGridTool.loadData(grid);
					}, 
					// 查询条件
					appendQueryFields = function(queryfields, $queryBar) {
						var $searchContent = $('<ul/>').addClass('searchContent');
						var searchContent = '';
						$.each(queryfields, function(index, query) {
							if (query.columnIndex !== undefined) {
								$.extend(query, columnToQuery(grid.options.columns[query.columnIndex]));
							}
							if (index % grid.options.query.numPerRow === 0) {
								if (searchContent) {
									searchContent.appendTo($queryBar);
								}
								searchContent = $searchContent.clone();
							}
							if (!query.field) {
								searchContent.append('<li/>');
								return true;
							}
							var $li = $('<li/>').append($('<label/>').text(query.text + queryColon)), $input;

							var attrObj = {};
							if (query.id)
								attrObj.id = query.id;
							if (query.field)
								attrObj.name = query.field;

							if (!query.type || query.type === 'text') {
								$input = $('<input type="text" autocomplete="off"/>').addClass('textInput').attr(attrObj).addClass(query.required ? 'required' : '').val(query.value || '');
								$li.append($input);
							} else if (query.type === 'date') {
								if (query.minDate)
									attrObj.minDate = query.minDate;
								if (query.maxDate)
									attrObj.maxDate = query.maxDate;
								if (query.min_date)
									attrObj.min_date = query.min_date;
								if (query.max_date)
									attrObj.max_date = query.max_date;
								if (query.dateGroup)
									attrObj.dateGroup = query.dateGroup;
								attrObj.readonly = 'readonly';
								attrObj.dateFmt = query.dateFmt || 'yyyy-MM-dd';
								$input = $('<input type="text" class="textInput date" />').addClass(query.required ? 'required' : '').attr(attrObj).val(query.value || '');
								$li.append($input).append($('<a class="inputDateButton" href="javascript:;" />'));
							} else if (query.type === 'select') {
								$input = $('<select/>').attr(attrObj).addClass(query.required ? 'required' : '');
								$.each(query.options, function() {
									$('<option/>').attr('value', this[query.value || 'value']).text(this[query.label || 'label']).appendTo($input);
								});
								$li.append($input).wrapInner($('<div/>').css('float', 'left'));
							}
							if ($input) {
								$input.addClass(query.css || '').on('change', function() {
									if ($.isFunction(query.change)) {
										query.change($input, $queryBar);
									}
								});
								if ($.isFunction(query.render)) {
									query.render($input);
								}
							}
							searchContent.append($li);
						});
						return searchContent;
					}, 
					// 普通查询
					createQueryPanel = function() {
						var $queryPanel = $('<div/>').addClass('pageHeader').attr('grid', grid._gridId), $queryBar = $('<div/>').addClass('searchBar'), searchContent = appendQueryFields(grid.options.query.queryfields, $queryBar);

						var queryBtn = $('<li/>').addClass('query').append($('<div class="buttonActive"/>').append($('<div class="buttonContent"/>').append($('<button/>').text(grid.options.query.button)))).appendTo(searchContent.appendTo($queryBar.appendTo($queryPanel)));

						var $btn = queryBtn.find('button').on('click', function() {
							$('#calendar', $('body')).remove();
							if ($form && !$form.valid()) {
								return false;
							}
							if (grid.options.pageable) {
								setPageNum(1);
							} else {
								$.jGridTool.loadData(grid);
							}
							return false;
						});
						$queryPanel.on('keydown', 'input, select', function(event) {
							var e = event || window.event;
							if (e.keyCode === 13) {
								if (!$('#alertMsgBox').is(':visible')) {
									setTimeout(function() {
										$btn.click();
									}, 0);
									return false;
								}
							}
						});
						grid.queryPanel = $queryPanel;
						return grid.queryPanel;
					}, 
					// 高级查询
					createAdvancedQueryPanel = function() {
						var speed = 400, $advancedQuery = $('<li/>').addClass('advancedQuery').append($('<a/>').append(advancedQueryText)).append($('<span/>')).appendTo($('.searchContent:last', grid.queryPanel)).on('click', 'a, span', function() {
							if (grid.advancedQueryPanel.is(':animated')) {
								return false;
							}
							var $gridPart = $this.find('.gridPart'), $gridBody = $this.find('.gridBody');
							if ($advancedQuery.is('.expand')) {
								grid.queryPanel.next('.divider').hide();
								grid.advancedQueryPanel.slideUp(speed, function() {
									$advancedQuery.removeClass('expand');
								});
								$gridPart.attr('layoutH', grid.options.layoutH - grid.options.gridHeaderHeight).height($gridPart.height() + 6).animate({
									height: $gridPart.height() + grid.options.query.advancedHeight - 6
								}, speed);
								$gridBody.attr('layoutH', grid.options.layoutH).height($gridBody.height() + 6).animate({
									height: $gridBody.height() + grid.options.query.advancedHeight - 6
								}, speed);
							} else {
								grid.queryPanel.next('.divider').show();
								grid.advancedQueryPanel.slideDown(speed, function() {
									$advancedQuery.addClass('expand');
								});
								$gridPart.attr('layoutH', grid.options.layoutH + grid.options.query.advancedHeight - grid.options.gridHeaderHeight).height($gridPart.height() - 7).animate({
									height: $gridPart.height() - grid.options.query.advancedHeight + 7
								}, speed);
								$gridBody.attr('layoutH', grid.options.layoutH + grid.options.query.advancedHeight).height($gridBody.height() - 7).animate({
									height: $gridBody.height() - grid.options.query.advancedHeight + 7
								}, speed);
							}
						});
						$('<div class="divider"/>').css({
							margin: '0px 10px'
						}).hide().insertAfter(grid.queryPanel);
						var $advancedQueryPanel = $('<div/>').addClass('pageHeader advancedQueryPanel').attr('grid', grid._gridId).hide(), $queryBar = $('<div/>').addClass('searchBar'), searchContent = appendQueryFields(grid.options.query.advancedqueryfields, $queryBar);
						$queryBar.append(searchContent).appendTo($advancedQueryPanel);
						grid.advancedQueryPanel = $advancedQueryPanel;
						grid.options.query.advancedHeight = 7 + $('.searchContent', $queryBar).length * 29 + 15;
						return grid.advancedQueryPanel;
					};
					appendGrid();
					if (grid.options.query.queryfields.length > 0) {
						grid.options.queryable = true;
						$form = $('<form/>').addClass('required-validate');
						createQueryPanel().appendTo($form);
					}
					if (grid.options.queryable && grid.options.query.advancedqueryfields.length > 0) {
						createAdvancedQueryPanel().appendTo($form);
					}
					if ($form) {
						$form.insertBefore($this);
					}
					if (grid.options.gridbars.length > 0) {
						createGridBar().prependTo($this);
					}
					if (grid.options.page && grid.options.pageable) {
						createPageBar().appendTo($this);
					}
					if (grid.options.hasBorder) {
						var borderWidth = '{0}px 1px {1}px 1px';
						if (grid.options.gridbars.length > 0) {
							borderWidth = borderWidth.replace('{0}', 0);
						} else {
							borderWidth = borderWidth.replace('{0}', 1);
						}
						if (grid.options.page && grid.options.pageable) {
							borderWidth = borderWidth.replace('{1}', 0);
						} else {
							borderWidth = borderWidth.replace('{1}', 1);
						}
						$this.css({
							borderWidth: borderWidth,
							borderStyle: 'solid',
							borderColor: '#D9DFE5'
						});
					}
					if (grid.options.url && grid.options.autoLoad) {
						$.jGridTool.loadData(grid);
					} else {
						$.jGridTool.fillGrid(grid, grid.options.fillData);
					}
					$this.data('_grid', grid);
				});
			} else if (typeof arguments[0] === "string" && arguments[0] !== 'option') {
				// 方法调用
				var gridFun = arguments[0], ops = arguments, gridFuns = ["fillGrid", "loadData", "lockColumn", "insertRow", "appendRow", "clearData", "refresh", "option"];
				return this.each(function() {
					if (gridFuns.indexOf && gridFuns.indexOf(gridFun) !== -1 || checkIndexOf(gridFuns, gridFun) !== -1) {
						var $this = $(this), _grid = $this.data('_grid');
						$.jGridTool[gridFun](_grid, ops[1], ops[2]);
					} else {
						console.error('$(...).jGrid("' + gridFun + '") is not a function.');
						return false;
					}
				});
			} else if (typeof arguments[0] === "string" && arguments[0] === 'option') {
				if (arguments[1] && $.isPlainObject(arguments[1])) {
					var ops = arguments[1];
					return this.each(function() {
						$.jGridTool.option($(this).data('_grid'), ops);
					});
				} else {
					if (this.length && this.length === 1) {
						var _grid = this.data('_grid');
						return _grid.options;
					} else if (this.length && this.length > 1) {
						var options = new Array();
						this.each(function() {
							var _grid = $(this).data('_grid');
							options.push(_grid.options);
						});
						return options;
					} else {
						return undefined;
					}
				}
			}
		}
	});

	$.jGridTool = {
		// ajax加载数据
		loadData: function(grid) {
			var data = arguments[1] || {};
			$.each(grid.thead.find('th:first input[type=checkbox]'), function() {
				this.checked = false;
			});
			if (!grid.options.url) {
				if (data.url) {
					grid.options.url = data.url;
					delete data.url;
				} else {
					console.error("There is no url to get the data.");
					return;
				}
			}
			var url = grid.options.base + grid.options.url;
			DWZ.debug(url);
			if (!url.isFinishedTm()) {
				return false;
			}
			data._gridId = grid._gridId;
			if (grid.options.queryable) {
				$.extend(data, $.jGridTool.getQueryData(grid));
			}
			if ($.isFunction(grid.options.getQueryData)) {
				$.extend(data, grid.options.getQueryData());
			}
			if (grid.options.pageable) {
				$.extend(data, grid.page);
			}
			var ordersString = "";
			$.each(grid.orders, function(field, orderType) {
				ordersString += (field + ' ' + orderType + ',');
			});
			// 后台排序
			if (!ordersString) {
				ordersString = grid.defaultOrderString;
			} else {
				ordersString = ordersString.slice(0, -1);
			}
			$.extend(data, {
				ordersString: ordersString
			});

			// 保存grid的查询数据
			grid.options.postData = $.extend({}, data);
			DWZ.ajax({
				url: url,
				data: data,
				alert: false,
				success: function(rs) {
					var json = new Object();
					if ($.isPlainObject(rs.data)) {
						json = rs.data;
					} else {
						json = rs;
					}
					//没有数据不加载
					if (json.totalCount <= 0) {
						var $tbody = grid.tbody, $tr = $('<tr/>');
						$tr = $.jGridTool.$blankTr.clone(true);
						$('>td>div', $tr).text($.validator.messages.noData || '======列表无数据=====');
						$tbody.html($tr)
						return;
					}
					if (grid.options.pageable && $.isPlainObject(json)) {
						if (json.numPerPage > json.totalCount && json.pageNum > 1) {
							grid.page.pageNum = 1;
							grid.page.startRow = 1;
							grid.page.endRow = json.numPerPage;
							$.jGridTool.loadData(grid);
							return;
						}
						$.jGridTool.setPagination(grid, {
							numPerPage: json.numPerPage,
							pageNum: json.pageNum,
							totalCount: json.totalCount,
							startRow: json.startRow,
							endRow: json.endRow
						});
					}
					if (json.data) {
						$.jGridTool.fillGrid(grid, json.data);
					} else {
						$.jGridTool.fillGrid(grid, json);
					}
					if ($.isFunction(grid.options.loadcomplete)) {
						grid.options.loadcomplete(json, grid);
					}
				}
			});
		},
		// 数据填充
		fillGrid: function(grid, data) {
			var $tbody = grid.tbody, $table = $tbody.parent(), $tr = $('<tr/>');
			$tbody.fadeOut(0, function() {
				if (data.length === 0) {
					$.jGridTool.clearData(grid);
					return;
				}
				$tbody.empty().detach();
				// 追加数据
				$.each(data, function(index, object) {
					$.jGridTool._addRowForObj(grid, index, object, $tbody);
				});
				$tbody.appendTo($table);
				var $ths = grid.thead.find(">tr:last-child>th"), $trs = $tbody.find(">tr:first>td");
				$.each($ths, function(index, th) {
					$($trs[index]).css('width', th.style.width);
				});
				$tbody.fadeIn(100, function() {
					if ($.isFunction(grid.options.fillcallback)) {
						grid.options.fillcallback($tbody);
					}
				});
			});
		},
		// 分页数据
		setPagination: function(grid, page) {
			grid.options.pagination = page;
			$('span[name="totalCount"]', grid.pagePanel).text(page.totalCount + pagePanelTotalItems);
			var totalPageNum = Math.ceil(page.totalCount / page.numPerPage);
			grid.pagination.data('totalPageNum', totalPageNum);
			$('>input:first', grid.jumpto).val(page.pageNum);
			if (page.pageNum < totalPageNum) {
				$.jGridTool.setPaginationAble(grid.nextPage, true);
				$.jGridTool.setPaginationAble(grid.lastPage, true);
			}
			if (page.pageNum > 1) {
				$.jGridTool.setPaginationAble(grid.firstPage, true);
				$.jGridTool.setPaginationAble(grid.prevPage, true);
			}
			if (page.pageNum === totalPageNum || totalPageNum === 0) {
				$.jGridTool.setPaginationAble(grid.nextPage, false);
				$.jGridTool.setPaginationAble(grid.lastPage, false);
			}
			if (page.pageNum === 1 || totalPageNum === 0) {
				$.jGridTool.setPaginationAble(grid.firstPage, false);
				$.jGridTool.setPaginationAble(grid.prevPage, false);
			}
			var firstNum = 1, lastNum = totalPageNum, pageNumShown = grid.options.page.pageNumShown;
			if (totalPageNum > pageNumShown) {
				if (totalPageNum - pageNumShown > page.pageNum) {
					firstNum = page.pageNum;
					lastNum = page.pageNum + pageNumShown - 1;
				} else {
					lastNum = totalPageNum;
					firstNum = totalPageNum - pageNumShown + 1;
				}
			}
			grid.prevPage.nextAll('.j-num').remove();
			for (var int = firstNum; int < (lastNum + 1); int++) {
				$('<li class="j-num"/>').addClass((int === page.pageNum) ? ' selected' : '').append($('<a href="javascript:;"/>').append(int).on('click', function() {
					var num = parseInt($(this).text());
					grid.page.pageNum = num;
					grid.page.startRow = (num - 1) * grid.page.numPerPage + 1;
					grid.page.endRow = num * grid.page.numPerPage;
					$.jGridTool.loadData(grid);
				})).hoverClass('hover').insertBefore(grid.nextPage);
			}
		},
		// 分页导航设置
		setPaginationAble: function($pb, able) {
			if (able) {
				$pb.removeClass('disabled');
				$pb.find('>a').show().css({
					color: '#000 !important'
				});
				$pb.find('>span').hide();
			} else {
				$pb.addClass('disabled');
				$pb.find('>a').hide();
				$pb.find('>span').show();
			}
		},
		// 获取查询条件输入
		getQueryData: function(grid) {
			var queryData = {};
			$.each($('[name]', grid.queryPanel), function() {
				var $this = $(this);
				queryData[$this.attr('name')] = $this.val() || $this[0].value;
			});
			if (grid.advancedQueryPanel) {
				$.each($('[name]', grid.advancedQueryPanel), function() {
					var $this = $(this);
					queryData[$this.attr('name')] = $this.val() || $this[0].value;
				});
			}
			return queryData;
		},
		// 锁定列/固定列
		lockColumn: function(grid) {
			var hLeft = grid.thead.parents('.gridThead:first').cssv("left");
			for (var columnIndex = 0; columnIndex < grid.options.lockColumnNum; columnIndex++) {
				var $th = $('tr:first > th:eq(' + columnIndex + ')', grid.thead);
				$('>:nth-child(' + (columnIndex + 1) + ')', $('tr', grid.thead.parents('.grid:first'))).addClass('lockColumn').css({
					width: $th[0].style.width,
					left: -hLeft
				});
			}
		},
		// 数据空行
		$blankTr: $('<tr/>').append($('<td/>').addClass("noData").append('<div/>')).on('click', function() {
			return false;
		}),
		// 添加行
		appendRow: function(grid, data) {
			this._addRow(grid, undefined, data);
		},
		// 插入行
		insertRow: function(grid, rowIndex, data) {
			if (!isNaN(rowIndex)) {
				this._addRow(grid, rowIndex, data);
			} else {
				this._addRow(grid, undefined, data);
			}
			var $tbody = grid.tbody;
			if (rowIndex === 0) {
				var $ths = grid.thead.find(">tr:last-child>th"), $trs = $tbody.find(">tr:first>td");
				$.each($ths, function(index, th) {
					$($trs[index]).css('width', th.style.width);
				});
			}
			var indexColumn = -1;
			$.each(grid.options.columns, function(index, field) {
				if (field.field === '_index') {
					indexColumn = index + 1;
					return false;
				}
			});
			if (indexColumn >= 0) {
				var _index = 1;
				$.each($('>td:nth-child(' + indexColumn + ')', $('>tr', $tbody)), function() {
					var $this = $(this);
					if ($('>div', $this).length) {
						$('>div', $this).text(_index++);
					} else {
						$this.text(_index++);
					}
				});
			}
		},
		_addRow: function(grid, index, data) {
			if (!data || $.isPlainObject(data)) {
				var $tbody = grid.tbody;
				if ($('>tr>.noData', $tbody).length === $('>tr', $tbody).length) {
					$tbody.empty();
				}
				this._addRowForObj(grid, index, data, $tbody);
			}
			// 后期可能会有数组
		},
		_addRowForObj: function(grid, index, object, $tbody, parentId, pLeft) {
			if (index === undefined) {
				index = $('>tr', $tbody).length;
			}
			var $tr = $('<tr/>').data('__index__', index).data('__source__', object);
			if (object) {
				$tr.data(object);
			}
			$.each(grid.options.columns, function(columnIndex, field) {
				var textValue = '', td = $('<td/>');
				if ($.isPlainObject(field)) {
					var columnField = field.field;
					if (field.type === 'checkbox') {
						var fieldSplit = field.fieldSplit || ';', text = '';
						if (object) {
							if (columnField.indexOf(fieldSplit) !== -1) {
								var checkFields = columnField.split(fieldSplit);
								$.each(checkFields, function() {
									text += object[this] + fieldSplit;
								});
								text = text.slice(0, -1);
							} else {
								text = object[columnField];
							}
						}
						if (!grid.options._shiftbox) {
							grid.options._shiftbox = field.group || '';
						}
						textValue = $('<input type="checkbox"/>').attr('name', field.group).val(text);
					} else if (field.type === 'date') { // 对于Date类型的数据进行格式化
						if (object && object[columnField]) {
							var date = new Date(parseInt(object[columnField]));
							textValue = date.formatDate(field.format ? field.format : "yyyy-MM-dd HH:mm:ss");
						}
					} else if (field.type === 'textInput') {
						textValue = $('<input class="textInput" type="text"/>').val(object[columnField]).addClass(field.inputClass || '');
					} else if (columnField === '_index') {
						if (grid.page) {
							textValue = index + grid.page.startRow;
						} else {
							textValue = index + 1;
						}
					} else if (columnField === '_lookup') {
						var $btnSelect = $('<a/>').addClass('btnSelect bringBack').text('选择'), backData = {};
						$.each(field.bringBackFields, function() {
							backData[this] = object[this];
						});
						textValue = $btnSelect.on('click', function() {
							$.bringBack(backData);
						});
					} else if ($.isFunction(field.transform)) {
						textValue = field.transform(object[columnField]);
					} else if (object) {
						textValue = object[columnField];
					}
				}
				if (grid.options.wrapTD || grid.options.lockColumnNum > columnIndex) {
					if (typeof textValue === 'string') {
						td.append($('<div/>').text(textValue));
					} else {
						td.append($('<div/>').append(textValue));
					}
				} else {
					if (typeof textValue === 'string') {
						td.text(textValue);
					} else {
						td.append(textValue);
					}
				}
				if ($.isFunction(field.tdrender)) {
					field.tdrender.call(textValue, grid.options.wrapTD ? td.find('>div') : td, object, field.field);
				}
				$tr.append(td.attr({
					columnField: field.field ? field.field : ''
				}));
			});
			var rowNums = $('>tr', $tbody).length;
			if (rowNums <= index || grid.options.treeTable) {
				$tbody.append($tr);
			} else {
				$tr.insertBefore($('>tr:eq(' + index + ')', $tbody));
			}
			if (rowNums === 0) {
				var $ths = grid.thead.find(">tr:last-child>th"), $trs = $tbody.find(">tr:first>td");
				$.each($ths, function(index, th) {
					$($trs[index]).css('width', th.style.width);
				});
			}
			// 树列表
			if (grid.options.treeTable) {
				var treeChildren = grid.options.childrenField, cId = parentId ? (parentId + index) : ('p' + index), modelClass = grid.options.treeModel || 'collapsed';

				$tr.attr({
					'data-tr_parent_id': parentId || '',
					'data-tr_id': cId
				}).addClass(modelClass);

				if (parentId && modelClass === 'collapsed') {
					$tr.hide();
				}

				var $d = (grid.options.wrapTD || grid.options.lockColumnNum > 0) ? $('>td:first>div', $tr) : $('>td:first', $tr);
				if (treeChildren && object[treeChildren] && object[treeChildren].length) {
					$d.prepend($('<span style="padding-left: ' + ((pLeft || 0) * 19) + 'px;" class="indenter"><a href="#">&nbsp;</a></span>').on('click', function() {
						if ($('>tr[data-tr_parent_id^=' + $tr.attr('data-tr_id') + ']:animated', $tbody).length) {
							return false;
						}
						if ($tr.is('.collapsed')) {
							$tr.removeClass('collapsed').addClass('expanded');
							$.jGridTool.treeExpand($tbody, $tr);
						} else {
							$('>tr[data-tr_parent_id^=' + $tr.attr('data-tr_id') + ']', $tbody).slideUp(200, function() {
								$tr.removeClass('expanded').addClass('collapsed');
							});
						}
						return false;
					}));
					$.each(object[treeChildren], function(i, obj) {
						$.jGridTool._addRowForObj(grid, i, obj, $tbody, cId, (pLeft || 0) + 1);
					});
				} else {
					$d.prepend('<span style="padding-left: ' + ((pLeft || 0) * 19 + 19) + 'px;" />');
				}
			}
		},
		// 树表展开
		treeExpand: function($tbody, $tr) {
			var trId = $tr.attr('data-tr_id');
			$('>tr[data-tr_parent_id=' + trId + ']', $tbody).each(function() {
				if ($tr.is('.expanded')) {
					$(this).slideDown(200);
					$.jGridTool.treeExpand($tbody, $(this));
				}
			});
		},
		// 列表样式刷新
		refresh: function(grid) {
			var $tbody = grid.tbody;
			if ($('>tr', $tbody).length === 0) {
				this.clearData(grid);
			} else {
				var $ths = $(">tr:last-child>th", grid.thead), $trs = $(">tr:first>td", $tbody);
				$.each($ths, function(index, th) {
					$($trs[index]).css('width', th.style.width);
				});
			}
		},
		// 获取/设置属性
		option: function(grid, ops) {
			if (ops && $.isPlainObject(ops)) {
				var needRefactor = (ops.columns && ops.columns !== grid.options.columns) || (ops.lockColumnNum && ops.lockColumnNum !== grid.options.lockColumnNum);
				$.extend(grid.options, ops);
				if (needRefactor) {
					$.jGridTool.clearData(grid);
					$.jGridTool.fillGridHeader(grid);
				}
			}
		},
		// 清空列表
		clearData: function(grid) {
			var $tbody = grid.tbody, $table = $tbody.parent(), $tr = this.$blankTr.clone(true);
			$('>td>div', $tr).text($.validator.messages.noData || '======列表无数据=====');
			$tbody.empty().detach().append($tr).appendTo($table).fadeIn(300);
			$('[type=checkbox]', grid.thead).removeAttr('checked');
		},
		// 生成表头
		fillGridHeader: function(grid, columns) {
			if (columns) {
				$.extend(true, grid.options, {
					columns: columns
				});
			}
			var $thead = grid.thead, $tbody = grid.tbody, $tr = $('<tr/>').appendTo($thead.css({
				height: grid.options.gridHeaderHeight
			}).empty()), $grid = $thead.parents('.gridPart:first'), $this = $grid.parent(), $gridHeader = $('>.gridHeader', $grid), $gridBody = $('>.gridBody', $grid), $gridScrollerBar = $('>.gridScrollerBar', $grid), $resizeMarker = $('>.resizeMarker', $grid), $resizeProxy = $('>.resizeProxy', $grid), gridWith = grid.options.hasBorder ? $this.width() - 1 : $this.width();
			if (grid.options.width === 0 || grid.options.width === '100%' || grid.options.width < $this.width()) {
				grid.options.width = $this.width();
			}
			if (grid.options.fixedWidth) {
				grid.options.width = grid.options.fixedWidth;
			}
			var tableWith = grid.options.width - 20;
			$('table', $gridHeader).css({
				width: tableWith
			});
			$('table', $gridBody).css({
				width: tableWith
			});

			$.each(grid.options.columns, function(columnIndex, column) {
				var $th = $('<th/>').addClass(column.align || '').attr({
					title: column.title || column.text || '',
					orderfield: column.field
				}).css({
					width: column.width - (100 * column.width / grid.options.width) - 2
				});
				$th.hoverClass("hover").append($('<div/>').addClass('gridCol').append(column.text || ''));
				if (column.type === 'checkbox') {
					grid.options.checkGroup = column.group;
					$th.find('.gridCol').append($('<input class="checkboxCtrl" type="checkbox" />').attr('group', column.group));
				}
				if ($.isFunction(column.thrender)) {
					column.thrender($th.find('.gridCol'));
				}
				if (column.query && column.query === true) {
					grid.options.query.queryfields.push(columnToQuery(column));
				}
				/*
				if (grid.options.query.queryfields.length) {
					grid.options.query.queryfields.sort(function(a, b) {
						if (a.index != undefined) {
							if (a.index > (b.index || -1)) {
								return 1;
							}
						}
						return -1;
					})
				}
				*/
				var orderSub = '';
				if (column.orderTable) {
					orderSub = column.orderTable + '.';
				}
				$th.on('click', '.gridCol', function() {
					if (!column.orderable) {
						column.orderable = grid.options.orderable;
					}
					var orderType = grid.options.ordertype, // 'multiple' ||
					// 'single';
					clearOrders = function() {
						if (orderType === 'single') {
							$('.asc, .desc', $tr).removeClass('asc desc');
							grid.orders = {};
						}
					};
					if (column.type !== 'checkbox' && column.field !== '_index' && column.field !== '_lookup' && column.orderable) {
						if ($th.hasClass('asc')) {
							clearOrders();
							$th.removeClass('asc');
							$th.addClass('desc');
							delete grid.orders[orderSub + column.field];
							grid.orders[orderSub + column.field] = "desc";
						} else if ($th.hasClass('desc')) {
							clearOrders();
							$th.removeClass('desc');
							delete grid.orders[orderSub + column.field];
						} else {
							clearOrders();
							$th.addClass('asc');
							delete grid.orders[orderSub + column.field];
							grid.orders[orderSub + column.field] = "asc";
						}
						$.jGridTool.loadData(grid);
					}
				});
				if (column.defaultOrder !== undefined) {
					grid.defaultOrderString = orderSub + column.field + ' ' + column.defaultOrder;
					if (column.orderIcon) {
						$th.addClass(column.defaultOrder);
					}
				}
				if (!grid.defaultOrderString && column.field.toLowerCase() === 'createdatetime') {
					grid.defaultOrderString = orderSub + 'createDateTime desc';
				}
				if (grid.options.lockColumnNum > columnIndex) {
					$th.addClass('lockColumn');
				}
				$th.appendTo($tr);
			});

			if (grid.options.lockColumnNum > 0) {
				$('table', $grid).addClass('lockColumnTable');
			} else {
				$('table', $grid).removeClass('lockColumnTable');
			}

			var _setScroll = function(gridWith) {
				var actualTableWidth = $(".gridThead > table", $gridHeader).width() || tableWith, hasScroller = false;
				if (actualTableWidth > gridWith) {
					$('>div', $gridScrollerBar).width(actualTableWidth + 20);
					$('>div', $gridScrollerBar).height(1).end().height(16);
					hasScroller = true;
				} else {
					$('>div', $gridScrollerBar).width(gridWith);
					$('>div', $gridScrollerBar).height(0).end().height(0);
				}
				var gridLayoutH = $grid.attr('layoutH');
				if (grid.options.layoutH > 0) {
					if (!gridLayoutH) {
						$grid.attr('layoutH', grid.options.layoutH - grid.options.gridHeaderHeight);
						$gridBody.attr('layoutH', grid.options.layoutH + (hasScroller ? 16 : 0));
					} else {
						$gridBody.attr('layoutH', parseInt(gridLayoutH) + grid.options.gridHeaderHeight + (hasScroller ? 16 : 0));
					}
				} else if (grid.options.height) {
					$grid.css({
						height: grid.options.height + grid.options.gridHeaderHeight
					});
					$gridBody.css({
						height: grid.options.height - (hasScroller ? 16 : 0)
					});
				}
				// 使layoutH生效
				$(window).resize();
			};
			_setScroll(gridWith);
			if (!grid.options.columnresizeable) {
				return;
			}
			$(">tr", $thead).each(function() {
				$(">th", this).each(function(i) {
					var th = this, $th = $(this);
					$th.mouseover(function(event) {
						var offset = $.jTableTool.getOffset(th, event).offsetX;
						if ($th.outerWidth() - offset < 5) {
							$th.css("cursor", "col-resize").mousedown(function(event) {
								$resizeProxy.show().css({
									left: $.jTableTool.getRight(th) - ($th.is('.lockColumn') ? 0 : $gridScrollerBar.scrollLeft()),
									top: $.jTableTool.getTop(th),
									height: $grid.height() - ($gridScrollerBar.width() < $gridScrollerBar[0].scrollWidth ? 16 : 0),
									zIndex: 100,
									cursor: "col-resize"
								});
								$resizeMarker.show().css({
									left: $.jTableTool.getLeft(th) + 1 - ($th.is('.lockColumn') ? 0 : $gridScrollerBar.scrollLeft()),
									top: $.jTableTool.getTop(th),
									height: $grid.height() - ($gridScrollerBar.width() < $gridScrollerBar[0].scrollWidth ? 16 : 0),
									zIndex: 100
								});
								$resizeProxy.jDrag($.extend({}, {
									scop: true,
									cellMinW: 20,
									relObj: $resizeMarker[0],
									move: "horizontal",
									event: event,
									stop: function() {
										var pleft = $resizeProxy.position().left;
										var mleft = $resizeMarker.position().left;
										var move = pleft - mleft - $th.outerWidth() - 9;

										var cols = $.jTableTool.getColspan($th);
										var cellNum = $.jTableTool.getCellNum($th);
										var oldW = $th.width(), newW = $th.width() + move;

										$th.width(newW + "px");
										$(">td:nth-child(" + cellNum + ")", $('tr', $tbody)).width(newW + "px");
										var newTableWidth = $thead.parent().width() - oldW + newW;
										$thead.parent().css({
											width: newTableWidth
										});
										$tbody.parent().css({
											width: newTableWidth
										});
										_setScroll();
										$(".resizeMarker,.resizeProxy", $grid).hide();
									}
								}));
							});
						} else {
							$th.css("cursor", $th.attr("orderField") ? "pointer" : "default");
							$th.unbind("mousedown");
						}
						return false;
					});
				});
			});
		}
	};

	// 针对不支持 Array.indexOf
	var checkIndexOf = function(items, item) {
		var _index = -1;
		$.each(items, function(index, value) {
			if (value === item) {
				_index = index;
				return false;
			}
		});
		return _index;
	};
	// 如果使用layoutH布局时，其父元素有绝对布局且设置class为layoutPanel时，改变窗口大小时需要改变自身的高度
	$(win).on('resize', function() {
		$.each($('.layoutPanel'), function() {
			var $layoutPanel = $(this);
			$.each($('[layoutH]', $layoutPanel), function() {
				var $this = $(this);
				$this.css({
					height: $layoutPanel.height() - parseInt($this.attr('layoutH'))
				});
			});
		});
	});
})(jQuery, window, DWZ, alertMsg, navTab);